module  sdram_read(
        input                       clk             ,
        input                       clk_3ns         ,
        
        input                       re              ,
        input           [15:0]      dq              ,
        input                       refresh_flag    ,
        input           [24:0]      addr            ,
        
        output          [1:0]       dqm             ,
        output          [12:0]      read_addr       ,
        output          [1:0]       read_ba         ,
        output          [ 2:0]      cmd             ,
        output  reg     [15:0]      data            ,
        output  reg                 read_end_flag
);

/////////////////////命令 ras_n cas_n we_n
parameter           [2:0]           CMD_PRECHARGE 		=       3'b010;
parameter           [2:0]           CMD_READ      		=       3'b101;
parameter           [2:0]           CMD_NOP       		=       3'b111;

////////////////////状态
reg[4:0] current_state ;
parameter
//空闲
idle_state                                      =       5'b00110,
//读
read_state                                      =       5'b01001,
NOP_read_state1                                 =       5'b01010,
NOP_read_state2                                 =       5'b01011,
NOP_read_state3                                 =       5'b00000,
//预充电
Precharge_state                                 =       5'b01100,
Precharge_NOP_state                             =       5'b01101;


///////////////////主程序
always @(posedge clk)//状态机
    begin
		
		case (current_state)
            idle_state:
                begin
                    if(re && !refresh_flag)
                        current_state=read_state;
                    else
                        current_state=idle_state;
                end
            read_state:
                begin
                    read_end_flag=1'b0;
                    current_state=NOP_read_state1;
                end
                NOP_read_state1://CAS_LATENCY = 2
                    begin
                        current_state=NOP_read_state2;
                    end
                NOP_read_state2://需要3个nop操作
                    begin
                        current_state=NOP_read_state3;
                    end
                NOP_read_state3:
                    begin					  
                            if(re && !refresh_flag)
                            begin
                                current_state=read_state;
                            end
                        else
                            begin
                                current_state=Precharge_state;
                            end 
                    end
            Precharge_state:
                begin
                    current_state=Precharge_NOP_state;
                end
                Precharge_NOP_state:// tRP 15ns
                    begin
                        read_end_flag=1'b1;
                        current_state=idle_state;
                    end
            default : current_state<=idle_state;
        endcase
    end		

//SDRAM时钟
always @(posedge clk_3ns )
begin
	if(current_state==NOP_read_state2)
		begin
			data<=dq;
		end
end

//命令
assign cmd =(current_state==read_state)?CMD_READ:(current_state==Precharge_state)?CMD_PRECHARGE:CMD_NOP;

//地址
assign {read_ba,read_addr}=(current_state==read_state)?{addr[24:23],3'b000,addr[9:0]}:(current_state==Precharge_state)? {15{1'b1}}:{15{1'b0}};

//数据掩码
assign dqm = (current_state==read_state|current_state==NOP_read_state1|current_state==NOP_read_state2|current_state==NOP_read_state3)?2'b00:2'b11; 

endmodule